home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / game / thomas / thomas.c < prev    next >
Text File  |  1993-07-08  |  13KB  |  535 lines

  1. /**/
  2.  
  3. #include <stdio.h>
  4. #include <egb.h>
  5. #include <mos.h>
  6. #include <snd.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10.  
  11. #define COLMOS 14
  12. #define COLWAK 32767
  13. #define COLMEN 8
  14. #define FILNLEN 128
  15. #define GAMXSZ 240
  16. #define GAMYSZ 240
  17. #define SPXMAX 25
  18. #define SPYMAX 25
  19. #define STEP    8
  20. #define DIRRIGHT  1
  21. #define DIRUP     2
  22. #define DIRLEFT   3
  23. #define DIRDOWN   4
  24. #define COMNOT    0
  25. #define COMMOV    1
  26. #define ABS(x) ((x)>0?(x):-(x))
  27. #define SndWorkSize 16384
  28. #define SNDDATASZ   64*1024
  29.  
  30. static char gwork[EgbWorkSize];
  31. static char mwork[MosWorkSize]; 
  32. static char swork[SndWorkSize];
  33. static char snddata1[SNDDATASZ];
  34. static char snddata2[SNDDATASZ];
  35. static char sndname1[FILNLEN]="thomas1.snd";
  36. static char sndname2[FILNLEN]="thomas2.snd";
  37. static char tifname[FILNLEN]="thomas.tif"; /* default tif file name */
  38. static int  moshs=0,moshe=638,mosvs=0,mosve=478;
  39. static char ramdata[GAMXSZ*GAMYSZ*2];
  40. static int  spx=4, spy=4, dotx, doty, datasize;
  41. static int  dir,rank,com;
  42. static char map[SPYMAX][SPXMAX];
  43. static int  runflag=1;
  44.  
  45. /**/
  46. int main(int argc, char *argv[])
  47. {
  48.  option(argc,argv);
  49.  screen();
  50.  loadtif();
  51.  loadsnd();
  52.  mkmap();
  53.  main_process();
  54.  end();
  55.  return 0;
  56. }
  57.  
  58. /**/
  59. main_process()
  60. {
  61.  int mb,mx,my;
  62.  while( runflag )
  63.   {
  64.   MOS_rdpos(&mb,&mx,&my);
  65.   switch(mb)
  66.    {
  67.    case 0: break;
  68.    case 1: 
  69.            switch(getmos1(mx,my))
  70.            {
  71.            case COMMOV:movmap();
  72.                        movpic();
  73.                        break; 
  74.           /*     case COMEND:runflag=0;break; */
  75.            }
  76.            break;
  77.    case 2: 
  78.            sndgo(20);
  79.            printhelp(mx,my);
  80.            break;
  81.    case 3: runflag=0; break;
  82.    default: break;
  83.    }
  84.   }
  85.  return 0;
  86. }
  87.  
  88. /**/
  89. option(int argc, char *argv[])
  90. {
  91.  int i,j,l;
  92.  char s[FILNLEN+1];
  93.  
  94.  for(i=1;i<argc;i++)
  95.   {
  96.   l=strlen(argv[i]);for(j=0;j<=l;j++) s[j]=tolower(argv[i][j]);
  97.   if( *s == '-' ) {option_size( argv[i] ); }
  98.   if( s[l-4]=='.' && s[l-3]=='t' && s[l-2]=='i' && s[l-1]=='f' )
  99.                   {strcpy(tifname,s); }
  100.   if( s[l-4]=='.' && s[l-3]=='s' && s[l-2]=='n' && s[l-1]=='d' )
  101.                   {strcpy(sndname2,sndname1);strcpy(sndname1,s); }
  102.   }
  103.  return 0;
  104. }
  105.  
  106. option_size(char *s)
  107.  int sz;
  108.  sz=atoi(++s);
  109.  if(sz>16) sz=16;
  110.  if(sz< 3) sz= 3;
  111.  spx=spy=sz;
  112.  return 0;
  113. }
  114.  
  115. loadsnd()
  116. {
  117.  FILE *fp;
  118.  if( (fp=fopen(sndname1,"rb"))!=NULL) 
  119.   { fread(snddata1,sizeof(char),SNDDATASZ,fp); 
  120.     if(DWORD(snddata1+12)>SNDDATASZ) DWORD(snddata1+12)=SNDDATASZ;
  121.     fclose(fp);}
  122.  if( (fp=fopen(sndname2,"rb"))!=NULL) 
  123.   { fread(snddata2,sizeof(char),SNDDATASZ,fp); 
  124.     if(DWORD(snddata2+12)>SNDDATASZ) DWORD(snddata2+12)=SNDDATASZ;
  125.     fclose(fp);}
  126.  return 0;
  127. }
  128. /**/
  129. sndgo(int n)
  130. {
  131. SND_pcm_play_stop(71);
  132. switch(n)
  133.   {
  134.    case  0:    SND_pcm_play(71,snddata1[28],127,snddata1);break;
  135.    case  1:    SND_pcm_play(71,snddata2[28],127,snddata2);break;
  136.    case 20:    SND_pcm_play(71,snddata2[28]+50,127,snddata2);break;
  137.    default:    break;
  138.   }
  139. return 0;
  140. }
  141. /**/
  142. end()
  143. {
  144.  MOS_end();
  145.  SND_end();
  146.  return 0;
  147. }
  148.  
  149. /**/
  150. screen()
  151. {
  152.  EGB_init(gwork,EgbWorkSize);   /* 画面初期化 */
  153.  EGB_resolution(gwork,0,3);     /* page=0;mode */
  154.  EGB_writePage(gwork,0);
  155.  EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
  156.  EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
  157.  EGB_displayStart(gwork,2,1,1); /* 拡大 */
  158.  EGB_displayStart(gwork,3,640,480); /* 画面のサイズ */
  159.  
  160.  EGB_resolution(gwork,1,10);     /* page=1;mode */
  161.  EGB_writePage(gwork,1);
  162.  EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
  163.  EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
  164.  EGB_displayStart(gwork,2,2,2); /* 拡大 */
  165.  EGB_displayStart(gwork,3,320,240); /* 画面のサイズ */
  166.  EGB_displayPage(gwork,0,3);        /* page0 前 page1,2表示 */
  167.  
  168.  SND_init(swork);
  169. /* SND_elevol_all_mute(0); */
  170.  SND_elevol_mute(1);
  171.  SND_pcm_mode_set(1);
  172.  MOS_start(mwork,MosWorkSize);
  173.  MOS_color(0,COLMOS);
  174.  MOS_horizon(moshs,moshe);
  175.  MOS_vertical(mosvs,mosve);
  176.  MOS_disp(1);
  177.  MOS_disp(3);
  178.  return 0;
  179. }
  180.  
  181. /**/
  182. loadtif()
  183. {
  184.  N_tifLoad( tifname,1,0,0);
  185.  return 0;
  186. }
  187.  
  188. /**/
  189. mkmap()
  190. {
  191.   int i,j,k;
  192.   dotx=GAMXSZ/spx; doty=GAMYSZ/spy;
  193.   datasize=dotx*doty*2;
  194.   char *ramp=ramdata;
  195.   for(j=0;j<spy;j++) for(i=0;i<spx;i++)
  196.   { k=j*spx+i;
  197.     map[j][i]=k;
  198.     N_getBlock( ramp, i*dotx, j*doty, (i+1)*dotx-1, (j+1)*doty-1);
  199.     ramp+=datasize;
  200.   }  
  201.  printmap();
  202.  return 0;
  203. }
  204.  
  205. /**/
  206. struct TIFTAG{
  207.          long  tagtype;
  208.          long  length;
  209.          long  value;
  210.         } ;
  211.  
  212. /**/
  213. N_tifLoad(char *filename,int page, int x, int y)
  214. {
  215. #define TIFWORKSIZE (320*240*2+0x0200)
  216.  char buf[TIFWORKSIZE];
  217.  struct TIFTAG * tag;
  218.  int   i,ret;
  219.  int   tagnum=0,sizex=0,sizey=0,doffs=0x0200;
  220.  
  221.  ret=N_fload(filename, buf, TIFWORKSIZE);
  222.  tagnum=(int) WORD(buf+0x0008);
  223.  tag=(struct TIFTAG *) (buf+0x000a);
  224.  for(i=0;i<tagnum;i++)
  225.   {
  226.   switch(tag->tagtype)
  227.     {
  228.     case 0x00030100:  sizex=tag->value; 
  229.                       break;
  230.     case 0x00030101:  sizey=tag->value;
  231.                       break;
  232.     case 0x00040111:  doffs=tag->value; 
  233.                       break;
  234.     default:          break;
  235.     }
  236.   tag++;
  237.   }
  238.  EGB_writePage(gwork,page);
  239.  EGB_writeMode(gwork,0);
  240.  N_putBlock( &buf[doffs], x, y, x+sizex-1, y+sizey-1);
  241.  return ret; 
  242. }
  243.  
  244. /**/
  245. int N_fload(char *fname, char *buf, int bufsize)
  246. {
  247.  FILE *fp1;
  248.  size_t fsize;
  249.  
  250.  fp1=fopen(fname, "rb");
  251.  if (fp1==NULL) {  fclose(fp1);  return(-1); }
  252.  fsize=fread(buf, 1, bufsize, fp1);
  253.  fclose(fp1);
  254.  return((int) fsize);
  255. }
  256.  
  257. /**/
  258. int N_putBlock( char *ptn, int sx, int sy, int ex, int ey)
  259. {
  260.  char gpara[14];
  261.  DWORD(gpara)=(unsigned int ) ptn;
  262.  WORD(gpara+4)=0x14;
  263.  WORD(gpara+6)=sx;
  264.  WORD(gpara+8)=sy;
  265.  WORD(gpara+10)=ex;
  266.  WORD(gpara+12)=ey;
  267.  return(EGB_putBlock(gwork,0,gpara));
  268. }
  269.  
  270. /**/
  271. int N_getBlock( char *ptn, int sx, int sy, int ex, int ey)
  272. {
  273.  char gpara[14];
  274.  DWORD(gpara)=(unsigned int ) ptn;
  275.  WORD(gpara+4)=0x14;
  276.  WORD(gpara+6)=sx;
  277.  WORD(gpara+8)=sy;
  278.  WORD(gpara+10)=ex;
  279.  WORD(gpara+12)=ey;
  280.  return(EGB_getBlock(gwork,gpara));
  281. }
  282.  
  283. getmos1(int x, int y)
  284. {
  285.   int eb, ex, ey;
  286.   dir=0;
  287.   com=COMNOT;
  288.   while(MOS_rdpos(&eb,&ex,&ey),eb==1);
  289.   switch(eb)
  290.    {
  291.    case 0: 
  292.            if(x<GAMXSZ*2 && y< GAMYSZ*2) {getdir(x,y,ex,ey);com=COMMOV;}
  293.            
  294.            break;
  295.    case 1: break;
  296.    case 2: break;
  297.    case 3: runflag=0; return com;
  298.    default: break;
  299.    }
  300.   return com;
  301. }
  302. /**/
  303. getdir(int x, int y, int ex, int ey)
  304. {
  305.  int wx, wy, ws, wt;
  306.  wx=ABS(ex-x); wy=ABS(ey-y); 
  307.  if( wx < 5 && wy < 5 )
  308.   {
  309.    wx=x-GAMXSZ; wy=y-GAMYSZ; 
  310.    ws=wx-wy; wt=wx+wy;
  311.    if( ws>=0 && wt>=0 ) dir=DIRRIGHT; /* right */
  312.    if( ws>=0 && wt<=0 ) dir=DIRUP   ; /* up    */
  313.    if( ws<=0 && wt<=0 ) dir=DIRLEFT ; /* left  */
  314.    if( ws<=0 && wt>=0 ) dir=DIRDOWN ; /* down  */
  315.   }
  316.  else 
  317.   {
  318.    wx=ex-x; wy=ey-y; 
  319.    ws=wx-wy; wt=wx+wy;
  320.    if( ws>=0 && wt>=0 ) dir=DIRRIGHT; /* right */
  321.    if( ws>=0 && wt<=0 ) dir=DIRUP   ; /* up    */
  322.    if( ws<=0 && wt<=0 ) dir=DIRLEFT ; /* left  */
  323.    if( ws<=0 && wt>=0 ) dir=DIRDOWN ; /* down  */
  324.   }
  325.  switch(dir)
  326.  {
  327.  case DIRRIGHT:rank=y/doty/2;break;
  328.  case DIRUP   :rank=x/dotx/2;break;
  329.  case DIRLEFT :rank=y/doty/2;break;
  330.  case DIRDOWN :rank=x/dotx/2;break;
  331.  }
  332.  return 0;
  333. }
  334. /**/
  335. movmap()
  336. {
  337.  int i,stnx,stny;
  338.  char xyb;
  339.  stnx=spx/3;
  340.  stny=spy/3;
  341.  switch(dir)
  342.  {
  343.  case DIRRIGHT:
  344.          if( rank<stny || spy-rank <= stny) return -1;
  345.          xyb=map[rank][spx-1];
  346.          for(i=spx-1;i>0;--i) map[rank][i]=map[rank][i-1];
  347.          map[rank][i]=xyb;
  348.          break;
  349.  case DIRUP:
  350.          if( rank<stnx || spx-rank <= stnx) return -1;
  351.          xyb=map[0][rank];
  352.          for(i=0;i<spy-1;i++) map[i][rank]=map[i+1][rank];
  353.          map[i][rank]=xyb;
  354.          break;
  355.  case DIRLEFT:
  356.          if( rank<stny || spy-rank <= stny) return -1;
  357.          xyb=map[rank][0];
  358.          for(i=0;i<spx-1;i++) map[rank][i]=map[rank][i+1];
  359.          map[rank][i]=xyb;
  360.          break;
  361.  case DIRDOWN:
  362.          if( rank<stnx || spx-rank <= stnx) return -1;
  363.          xyb=map[spy-1][rank];
  364.          for(i=spy-1;i>0;--i) map[i][rank]=map[i-1][rank];
  365.          map[i][rank]=xyb;
  366.          break;
  367.  }
  368.  return 0;
  369. }
  370. movpic()
  371. {
  372.  int x1,y1,x2,y2,stnx,stny;
  373.  char para[64],buf[320*240*2];
  374.  stnx=spx/3;
  375.  stny=spy/3;
  376.  EGB_writePage(gwork,1);
  377.  if( rank<=0 ) goto error1;
  378.  switch(dir)
  379.  {
  380.  case DIRRIGHT:
  381.          if( rank<stny || spy-rank <= stny) goto error1;
  382.            { 
  383.              sndgo(0);
  384.              x1=(spx-1)*dotx;x2=x1+dotx-1;y1=rank*doty;y2=y1+doty-1; 
  385.              N_getBlock( buf, x1,y1,x2,y2);
  386.              WORD(para+0)=0;
  387.              WORD(para+2)=y1;
  388.              WORD(para+4)=x2;
  389.              WORD(para+6)=y2;
  390.              EGB_partScroll(gwork,0,dotx,0,para);
  391.              x1=0;x2=dotx-1; 
  392.              N_putBlock( buf,x1,y1,x2,y2);
  393.            }
  394.         break;
  395.  case DIRUP:
  396.          if( rank<stnx || spx-rank <= stnx) goto error1;
  397.            {
  398.              sndgo(0);
  399.              x1=rank*dotx;x2=x1+dotx-1;y1=0;y2=doty-1; 
  400.              N_getBlock( buf, x1,y1,x2,y2);
  401.              y1=(spy-1)*doty;y2=y1+doty-1; 
  402.              WORD(para+0)=x1;
  403.              WORD(para+2)=0;
  404.              WORD(para+4)=x2;
  405.              WORD(para+6)=y2;
  406.              EGB_partScroll(gwork,0,0,-doty,para);
  407.              N_putBlock( buf,x1,y1,x2,y2);
  408.            }
  409.          break;
  410.  case DIRLEFT:
  411.          if( rank<stny || spy-rank <= stny) goto error1;
  412.            {
  413.              sndgo(0);
  414.              x1=0;x2=dotx-1;y1=rank*doty;y2=y1+doty-1; 
  415.              N_getBlock( buf, x1,y1,x2,y2);
  416.              x1=(spx-1)*dotx;x2=x1+dotx-1; 
  417.              WORD(para+0)=0;
  418.              WORD(para+2)=y1;
  419.              WORD(para+4)=x2;
  420.              WORD(para+6)=y2;
  421.              EGB_partScroll(gwork,0,-dotx,0,para);
  422.              N_putBlock( buf,x1,y1,x2,y2);
  423.            }
  424.          break;
  425.  case DIRDOWN:
  426.          if( rank<stnx || spx-rank <= stnx) goto error1;
  427.            { 
  428.              sndgo(0);
  429.              x1=rank*dotx;x2=x1+dotx-1;y1=(spy-1)*doty;y2=y1+doty-1; 
  430.              N_getBlock( buf, x1,y1,x2,y2);
  431.              WORD(para+0)=x1;
  432.              WORD(para+2)=0;
  433.              WORD(para+4)=x2;
  434.              WORD(para+6)=y2;
  435.              EGB_partScroll(gwork,0,0,doty,para);
  436.              y1=0;y2=doty-1; 
  437.              N_putBlock( buf,x1,y1,x2,y2);
  438.            }
  439.          break;
  440.  }
  441.  return 0;
  442. error1:
  443.  sndgo(1);return -1;
  444. }
  445.  
  446. printmap()
  447. {
  448.  int i,j;
  449.  char *ramp=ramdata;
  450.   for(j=0;j<spy;j++) for(i=0;i<spx;i++)
  451.   { int x1,x2,y1,y2;
  452.     ramp=ramdata+datasize*map[j][i];
  453.     x1=i*dotx;y1=j*doty;x2=x1+dotx-1;y2=y1+doty-1;
  454.     EGB_writePage(gwork,1);
  455.     N_putBlock( ramp, x1, y1, x2, y2);
  456.     rectangle( x1,y1,x2,y2,0,COLWAK);
  457.   }  
  458.  {
  459.  int stnx=spx/3,stny=spy/3;
  460.  char hat[]={0xff,0x00,0xff,0x00};
  461.  EGB_writePage(gwork,0);
  462.  EGB_hatchingPattern(gwork,2,1,4,hat);
  463.  EGB_paintMode(gwork,0x82);
  464.  EGB_color(gwork,2,COLMEN);
  465.  rectangle( 0,               0,stnx*dotx-1,  stny*doty-1, 0,COLWAK);
  466.  rectangle( 0, (spy-stny)*doty, stnx*dotx-1, spy*doty-1,  0,COLWAK);
  467.  rectangle( (spx-stnx)*dotx, 0, spx*dotx-1,  stny*doty-1, 0,COLWAK);
  468.  rectangle( (spx-stnx)*dotx,(spy-stny)*doty, spx*dotx-1, spy*doty-1, 0,COLWAK);
  469.  EGB_paintMode(gwork,0x02);
  470.  }
  471.  return 0;
  472. }
  473.  
  474. rectangle(int x1, int y1, int x2, int y2, int page, int color)
  475. {
  476.  MOS_disp(2);
  477.  char para[64];
  478.  EGB_writePage(gwork,page);
  479.  EGB_color(gwork,0,color);
  480.  WORD(para+0)=x1*2;
  481.  WORD(para+2)=y1*2;
  482.  WORD(para+4)=x2*2+1;
  483.  WORD(para+6)=y2*2+1;
  484.  EGB_rectangle(gwork,para);
  485.  MOS_disp(3);
  486.  return 0;
  487. }
  488.  
  489. sjisStringCall(int x, int y, char *str)
  490. {
  491.   char para[64];
  492.   WORD(para+0)=x;
  493.   WORD(para+2)=y+20;
  494.   WORD(para+4)=strlen(str);
  495.   strcpy(para+6,str);
  496.   MOS_disp(2);
  497.   EGB_sjisString(gwork,para);
  498.   MOS_disp(3);
  499.   return 0;
  500. }
  501.  
  502. printhelp(int mx, int my)
  503. {
  504.   char buf[TIFWORKSIZE];
  505.   int x1,y1,x2,y2,btn,x,y;
  506.   if( mx < 0 ) { x1= 0,x2=x1+320; }
  507.     else if(mx>639-320) {x2=639,x1=x2-320;}
  508.       else { x1=mx,x2=x1+320;}
  509.   if( my < 0 ) { y1= 0,y2=y1+164; }
  510.     else if(my>479-164) {y2=479,y1=y2-164;}
  511.       else { y1=my,y2=y1+164;}
  512.   EGB_writePage(gwork,0);
  513.   MOS_disp(2);
  514.   N_getBlock( buf, x1, y1, x2, y2);
  515.   MOS_disp(3);
  516.   EGB_writeMode(gwork,0);
  517.   EGB_paintMode(gwork,0x22);
  518.   rectangle( x1/2+1, y1/2+1, x2/2-1, y2/2-1, 0, 13);
  519.   EGB_color(gwork,0,15);
  520.   sjisStringCall(x1+16,y1    ," ==操作説明==");
  521.   sjisStringCall(x1+16,y1+ 20,"[左ボタンをドラッグする]");
  522.   sjisStringCall(x1+16,y1+ 40,"    ドラッグした方向に絵が動く。");
  523.   sjisStringCall(x1+16,y1+ 60,"    ただし、角の絵は動かせない。");
  524.   sjisStringCall(x1+16,y1+ 80,"[右ボタンを押し続ける]");
  525.   sjisStringCall(x1+16,y1+100,"    操作説明画面が表示される。");
  526.   sjisStringCall(x1+16,y1+120,"[左右ボタン両方を押す]");
  527.   sjisStringCall(x1+16,y1+140,"    終了する。");
  528.   while(MOS_rdpos(&btn,&x,&y),btn==2);
  529.   MOS_disp(2);
  530.   N_putBlock( buf, x1, y1, x2, y2);
  531.   MOS_disp(3);
  532.   return 0;
  533. }
  534.